<template lang="pug">
  div(v-if="config.selectAppType === 'picker'")
    el-form-item(ref="formItem" v-if='!scope' :class="config.label?'':'form-label-hidden'"  :prop="config.propertyName" :rules="rules" label-width="0px")
      van-field(readonly clickable :label="config.label" :value="value" :placeholder="readonly?' ':config.placeholder" @click="clickShowPike" )
      van-popup(v-model="showPicker" position="bottom" )
        van-picker(show-toolbar :columns="options" @cancel="clickHidePike" @confirm="onConfirm" @change="change")
    div(v-else)
      van-field(readonly clickable :label="config.label" :value="value" :placeholder="readonly?' ':config.placeholder" @click="clickShowPike"  :title="scope[config.propertyName]")
      van-popup(v-model="showPicker" position="bottom" )
        van-picker(show-toolbar :columns="options" @cancel="clickHidePike" @confirm="onConfirm" @change="change")
  div(v-else)
    el-form-item(v-if='!scope' ref="formItem" :prop="config.propertyName" label-width="0px" :rules="rules")
      requiredLabel(:required="required" :label="config.label")
      tree-select.tree-select(:required="required" :disabled="readonly" @input="change" v-model="rootForm.properties[config.propertyName]" :valueFormat="config.returnObject?'object':'id'" :async="config.loadType === 'async'&&config.connectType==='interface'?true:false" :load-options="debounceRemoteMethod" :value-consists-of="valueConsistsOf" :normalizer="normalizer" :placeholder="readonly?' ':config.placeholder" :multiple="config.selectType === 'multiple'" :options="options"
      :defaultOptions="config.loadType === 'async'&&config.connectType==='interface'?true:false" @open="menuOpen" @close="menuClose"  noOptionsText="无数据" noResultsText="无匹配数据" noChildrenText="无子节点" :appendToBody="true" :z-index="9999999999999")
      //-
      //-
    //- el-form-item(v-else :prop="config.propertyName" label-width="0px" :rules="rules")
    div(v-else)
      requiredLabel.scope-label(:required="required" :label="config.label")
      tree-select.tree-select(:class="{'scope-success':flag&&!scopeErrorMessage,'scope-normal':!flag}" :required="required" :disabled="readonly" @input="change" v-model="scope[config.propertyName]" :valueFormat="config.returnObject?'object':'id'" :async="config.loadType === 'async'&&config.connectType==='interface'?true:false" :load-options="debounceRemoteMethod" :value-consists-of="valueConsistsOf" :normalizer="normalizer" :placeholder="readonly?' ':config.placeholder" :multiple="config.selectType === 'multiple'" :options="options"
      :defaultOptions="config.loadType === 'async'&&config.connectType==='interface'?true:false" @open="menuOpen" @close="menuClose"   noOptionsText="无数据" noResultsText="无匹配数据" noChildrenText="无子节点" :appendToBody="true" :z-index="9999999999999")
      .scope-error-message {{scopeErrorMessage}}

</template>
<script>
import _ from 'lodash'
import requiredLabel from '../../../../components/requiredLabel'
import inputCommon from '../../../../mixin/inputCommon'
import { invokeInterface, getDictionaryList } from '../../../../service'

import treeSelect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
  name: 'render',
  components: { requiredLabel, treeSelect },
  props: ['config', 'editor', 'isMobile', 'scope', 'cancelLinkAndDefaultValue', 'readonlyMain'],
  inject: ['rootForm'],
  mixins: [inputCommon],
  data() {
    return {
      value: null,
      showPicker: false,
      defaultFlag: false,
      options: [],
      valueConsistsOf: 'ALL', // 选中所有子节点 则展示所有选中的 BRANCH_PRIORITY LEAF_PRIORITY ALL_WITH_INDETERMINATE

      loading: false,
      cachedOptions: [],
      overLimitState: false, // 查询条数的提示语
      default: this.config.selectType === 'single' ? undefined : [],
      debounceRemoteMethod: _.debounce(this.remoteMethod, 300),
      scopeErrorMessage: '',
      flag: false // 还未被验证
    }
  },
  methods: {
    onConfirm(value) {
      if (this.scope) {
        this.scope[this.config.propertyName] = typeof value === 'object' ? value.value : value
      }else{
        this.rootForm.properties[this.config.propertyName] = typeof value === 'object' ? value.value : value
      }
      this.value = typeof value === 'object' ? value.label : value
      this.showPicker = false
      return this.config.blurCb && this.getParsedFn('blurCb')()
    },
    clickHidePike() {
      this.showPicker = false
      // return this.config.blurCb && this.getParsedFn('blurCb')()
    },
    clickShowPike() {
      if (this.readonly) return
      this.showPicker = true
      return this.config.focusCb && this.getParsedFn('focusCb')()
    },
    dealTreeOptions() {
      if (!this.config.isTreeSelect) {
        _.forEach(this.options, one => {
          if (one.children) {
            one.children = JSON.stringify(one.children)
          }
        })
      }
    },
    change() {
      this.$refs.formItem &&
        this.$refs.formItem.$emit(
          'el.form.change',
          this.rootForm.properties[this.config.propertyName]
        );
      this.validate();
      let obj = this.options.find(one => one.value == this.rootForm.properties[this.config.propertyName])
      return this.config.changeCb && this.getParsedFn('changeCb')(this.rootForm.properties[this.config.propertyName], obj);
    },
    normalizer(node) {
      let idKey = this.config.optionsValueKey
      let labelKey = this.config.optionsLabelKey
      let childrenKey = 'children'
      return {
        id: node[idKey] || node[labelKey],
        label: node[labelKey],
        children: node[childrenKey]
      }
    },
    remoteMethod({ action, searchQuery, callback }) {
      if (action === 'ASYNC_SEARCH') {
        // 异步初始值
        if (this.defaultFlag) {
          this.options = []
          let propertyNameVal = this.getValue()
          if (propertyNameVal) {
            if (this.config.returnObject) {
              if (_.isArray(propertyNameVal)) {
                this.options = propertyNameVal
              } else {
                this.options = [propertyNameVal]
              }
              this.dealTreeOptions()
              callback(null, this.options)
            } else {
              let searchQuery
              if (_.isArray(propertyNameVal)) {
                searchQuery = propertyNameVal
              } else {
                searchQuery = [propertyNameVal]
              }
              let searchQueryArr = _.map(searchQuery, one => {
                if (one) {
                  return this.getOptions(one)
                }
              })
              Promise.all(searchQueryArr).then(data => {
                _.forEach(data, one => {
                  this.options = _.uniqWith(one.concat(this.options), _.isEqual)
                })

                callback(null, this.options)
              })
            }
          }
          this.defaultFlag = false
        } else {
          this.getCachedOptions()
          this.getOptions(searchQuery).then(data => {
            if (this.config.selectType === 'multiple') {
              this.options = _.uniqWith(data.concat(this.cachedOptions), _.isEqual)
            } else {
              this.options = data
            }
            callback(null, this.options)
          })
        }
      }
    },
    // 聚焦事件
    menuOpen() {
      return this.config.focusCb && this.getParsedFn('focusCb')()
    },
    // 失去焦点事件
    menuClose() {
      return this.config.blurCb && this.getParsedFn('blurCb')()
    },
    getValue() {
      if (this.scope) {
        return this.scope[this.config.propertyName]
      } else {
        return this.rootForm.properties[this.config.propertyName]
      }
    },
    getCachedOptions() {
      let val = this.getValue()
      this.cachedOptions = []
      if (val) {
        if (this.config.returnObject) {
          if (_.isArray(val)) {
            this.cachedOptions = val
          } else {
            this.cachedOptions = [val]
          }
        } else {
          if (_.isArray(val)) {
            _.forEach(this.options, one => {
              if (val.indexOf(one[this.config.optionsValueKey]) > -1) {
                this.cachedOptions.push(one)
              }
            })
          } else {
            _.forEach(this.options, one => {
              if (val === one[this.config.optionsValueKey]) {
                this.cachedOptions.push(one)
              }
            })
          }
        }
      }
    },
    getOptions(query) {
      this.loading = true
      let params = {}
      if (query) {
        params[this.config.queryKey] = query
      }
      if (this.interfaceParams) {
        try {
          let varParams = this.interfaceParams
          params = Object.assign(varParams, params)
        }
        catch {
          this.$message({
            type: 'error',
            message: '参数格式错误'
          })
          return
        }
      }
      return invokeInterface(this.config.dataInterfaceId, params).then((data) => {
        this.loading = false
        return data
      })
    },
    // 针对scope的验证
    validate() {
      if (this.scope) {
        this.flag = true
        let value = this.scope[this.config.propertyName]
        if (this.required && (!value || !value.length)) {
          this.scopeErrorMessage = '必填项'
          return false
        }
        this.scopeErrorMessage = ''
        return true
      }
    }
  },
  created() {
    // 关联值变化了  初始化数据刷新
    if (this.config.connectType === 'interface' && this.config.linkSearch) {
      this.$watch(this.getParsedEx('linkSearchEx'), (newValue) => {
        this.rootForm.properties[this.config.propertyName] = this.default
        this.getOptions().then(data => {
          this.options = data
        })
      })
    }
    if (this.config.selectAppType == 'picker') {
      this.config.connectType = 'dictionary'
    }

    if (this.scope && this.scope[this.config.propertyName] === undefined) {
      this.scope[this.config.propertyName] = this.default
    }

    // 是否为(接口)搜索还是直接（字典）
    if (this.config.connectType === 'dictionary' && this.config.dataDictionaryId) {
      this.options = []
      // 当返回对象且直接加载时，页面显示的信息会等获取数据接口成功才回显，并不会直接拿对象里的数据
      if (this.config.returnObject && this.config.selectType === 'single' && this.getValue()) {
        this.options = [this.getValue()]
      } else if (this.config.returnObject && this.config.selectType === 'multiple' && this.getValue() && this.getValue().length > 0) {
        this.options = this.getValue()
      }
      this.dealTreeOptions()

      this.config.optionsValueKey = 'value'
      this.config.optionsLabelKey = 'label'
      getDictionaryList(this.config.dataDictionaryId).then(data => {
        this.options = _.cloneDeep(data)
        if (this.config.selectAppType == 'picker') {
          this.options.map(one => {
            one.text = one.label
            if (this.scope && (one.value == this.scope[this.config.propertyName] || one.value == this.rootForm.properties[this.config.propertyName])) {
              this.value = one.label
            }
          })
        }
        this.dealTreeOptions()
      })
    } else if (this.config.connectType === 'interface') {
      if(this.config.interfaceParams){
        this.interfaceParams = this.getParsedEx('interfaceParams')()
      }

      if (this.$route.path.indexOf('preview') === -1) {
        if (window.sessionStorage.formConfig) {
          let oldConfig = JSON.parse(window.sessionStorage.formConfig)

          if (oldConfig.dataInterfaceId === this.config.dataInterfaceId && this.config.searchClick === oldConfig.searchClick) {
            return
          }else{
            window.sessionStorage.setItem('formConfig', JSON.stringify(this.config))
          }
        }else{
          window.sessionStorage.setItem('formConfig', JSON.stringify(this.config))
        }
      }
      this.options = []
      // 当返回对象且直接加载时，页面显示的信息会等获取数据接口成功才回显，并不会直接拿对象里的数据
      if (this.config.returnObject && this.config.selectType === 'single' && this.getValue()) {
        this.options = [this.getValue()]
      } else if (this.config.returnObject && this.config.selectType === 'multiple' && this.getValue() && this.getValue().length > 0) {
        this.options = this.getValue()
      }
      this.dealTreeOptions()
      if (this.config.dataInterfaceId) {
        if (this.config.loadType === 'async') {
          // 远程搜索
          this.defaultFlag = true
        } else {
          this.getOptions().then(data => {
            this.options = data
            this.dealTreeOptions()
          })
        }
      }
    }
  }
}
</script>
